/**
 * 1.状态如何改变
 * 2.执行多个回调
 * 3.改变状态与指定回调的顺序
 * 4.then方法返回的结果
 * 5.串联多个任务
 * 6.异常穿透
 * 7.终端promise链条
 */
function Promise (executor) {
    this.promiseState = "pending"
    this.promiseResult = null
    this.eventList = []
    const _this = this
    function resolve(data){
        //修改状态
        //设置结果值
        //只能改变一次
        if(_this.promiseState !== "pending") return
        _this.promiseState = 'fulfilled'
        _this.promiseResult = data
        _this.eventList.forEach(element => {
            element.onResolved()
        });
    }
    function reject(reason){
        if(_this.promiseState !== "pending") return
        _this.promiseState = 'rejected'
        _this.promiseResult = reason
        _this.eventList.forEach(element => {
            element.onRejected()
         });
    }
    try{
        executor(resolve,reject)
    }
    catch(e){
        reject(e)
    }
   
}

Promise.prototype.then = function(onResolved,onRejected){
    const _this =  this
    if( typeof onRejected !== 'function'){
        onRejected = reason => {throw reason}
    }
    if( typeof onResolved !== 'function'){
        onResolved = value => value
    }
    // new方法返回一个promise,其状态由其指定函数返回的结果确定
    return new Promise((resolve,reject)=>{
        function callback(type){
             //抛出错误的情况
             try {
                //为了使then方法放回的promise有结果，则需要对函数onResolved的返回值进行判断
                const result = type(_this.promiseResult) // 传入成功结果值
                if(result instanceof Promise){
                    result.then(v=>{
                        resolve(v)
                    },r=>{
                        reject(r)
                    })
                }else{
                    resolve(result)
                }  
            } catch (error) {
                reject(error)
            }
        }
        if(_this.promiseState === 'fulfilled' ){
            //抛出错误的情况
            callback(onResolved)
        }
        if(_this.promiseState === 'rejected' ){
            callback(onRejected)
        }
        //由于异步时状态还未改变，所以需要增加在pending状态储存回调的操作，达到异步的效果
        if(_this.promiseState === 'pending' ){
            _this.eventList.push({
                onResolved:function(){
                    callback(onResolved)
                },
                onRejected:()=>{
                    callback(onRejected)
                }
            })
        }
    })
}

Promise.prototype.catch = function(onRejected){
    return this.then(null,onRejected)
}

Promise.resolve = function(value){
    return new Promise((resolve,reject)=>{
        if(value instanceof Promise){
            value.then(v=>{
                resolve(v)
            },r=>{
                reject(r)
            })
        }else{
            resolve(value)
        }
    })
}

Promise.reject = function(value){
    return new Promise((resolve,reject)=>{
        reject(value)
    })
}

Promise.all = function(list){
    return new Promise((resolve,reject)=>{
        const result = []
        let succuss = 0 
        list.forEach((item,index)=>{
            item.then(res=>{
                result[index] = res
                succuss++
                //放在循环内部更改状态
                if(succuss===list.length){
                    resolve(result)
                }
            },rej=>{
                    reject(rej) //失败要在这个位置写
            })
        })
    })
}

Promise.race = function(list){
return new Promise((resolve,reject)=>{
    list.forEach((item=>{
        item.then(res=>{
            resolve(res)
        },rej=>{
            reject(rej)
        })
    }))
})
}
